import * as Cesium from 'cesium'
import api from '@/api/request'
import { useMetroStore } from '@/store/metroStore'

export function renderTrains(viewer, lineId) {
  const metroStore = useMetroStore()
  const eventRemovers = []
  let trainEntity = null

  // 清理函数
  const cleanup = () => {
    eventRemovers.forEach(remover => remover())
    if (trainEntity) {
      viewer.entities.remove(trainEntity)
    }
  }

  try {
    api.get(`/api/trains/${lineId}`)
      .then((trainData) => {
        const { path, speed, passengerCount, modelUrl } = trainData
        const distance = calculateDistance(path)
        const timeSum = distance / speed
        const startTime = Cesium.JulianDate.now()
        const endTime = Cesium.JulianDate.addSeconds(
          startTime,
          timeSum,
          new Cesium.JulianDate()
        )

        const positionProperty = new Cesium.SampledPositionProperty()
        path.forEach((coordinate, index) => {
          const time = Cesium.JulianDate.addSeconds(
            startTime,
            index * (timeSum / path.length),
            new Cesium.JulianDate()
          )
          positionProperty.addSample(
            time,
            Cesium.Cartesian3.fromDegrees(...coordinate, 50)
          )
        })

        trainEntity = viewer.entities.add({
          position: positionProperty,
          model: {
            uri: modelUrl || import.meta.env.VITE_TRAIN_MODEL_URL || '/models/train.glb',
            scale: 0.5,
            minimumPixelSize: 64,
          },
          description: `<div class="train-popup">车内人数：${passengerCount}</div>`,
        })

        let metroIndex = 0
        const totalStations = path.length
        const tickHandler = viewer.clock.onTick.addEventListener((clock) => {
          const currentTime = clock.currentTime
          const currentPosition = positionProperty.sample(currentTime)
          if (metroIndex < totalStations - 1) {
            const nextCoordinate = path[metroIndex + 1]
            const distanceToNext = Cesium.Cartesian3.distance(
              currentPosition,
              Cesium.Cartesian3.fromDegrees(...nextCoordinate, 50)
            )
            if (distanceToNext < 50) {
              metroIndex++
              viewer.clock.shouldAnimate = false
              setTimeout(() => {
                viewer.clock.shouldAnimate = true
              }, 2000)
              metroStore.updateArrivalInfo(
                metroStore.stations[lineId][metroIndex],
                new Date().toLocaleTimeString()
              )
            }
          }
        })
        eventRemovers.push(() => viewer.clock.onTick.removeEventListener(tickHandler))

        viewer.clock.startTime = startTime.clone()
        viewer.clock.stopTime = endTime.clone()
        viewer.clock.currentTime = startTime.clone()
        viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP
        viewer.clock.multiplier = 1
        viewer.clock.shouldAnimate = true
      })
      .catch(error => {
        console.error('Failed to render trains:', error)
        cleanup()
      })

    return cleanup
  } catch (error) {
    console.error('Train rendering initialization failed:', error)
    cleanup()
    throw error
  }
}

function calculateDistance(points) {
  let total = 0
  for (let i = 1; i < points.length; i++) {
    const lon1 = points[i - 1][0],
      lat1 = points[i - 1][1]
    const lon2 = points[i][0],
      lat2 = points[i][1]
    total += Cesium.Cartesian3.distance(
      Cesium.Cartesian3.fromDegrees(lon1, lat1),
      Cesium.Cartesian3.fromDegrees(lon2, lat2)
    )
  }
  return total
}
